﻿using System;
using System.Collections.Generic;
using System.Text;
using Unis.Framework.ORM;
using Unis.Framework.ORM.BaseDefiniens.Enums;
using Unis.Framework.ORM.Common;
using Unis.Framework.ORM.Mapping;
using Unis.ORM.Mapping;
using Unis.ORM.Common;

namespace Unis.ORM.DbSql
{
    public class BaseAutoSqlGenerator : BaseSqlGenerator
    {
        // Methods
        public override SqlString[] GenerateDeleteSql(Type entityType)
        {
            SqlString str = null;
            ModelMappingInfo modelMappingInfo = AttMappingManager.Instance.GetModelMappingInfo(entityType);
            string mapTable = modelMappingInfo.MapTable;
            List<SqlParamInfo> sqlParams = new List<SqlParamInfo>();
            List<string> list2 = this.prepareDeleteSql(modelMappingInfo, ref sqlParams);
            StringBuilder builder = new StringBuilder();
            builder.Append(" DELETE FROM ").Append(mapTable).Append(" WHERE ").Append(string.Join(" AND ", list2.ToArray()));
            str = new SqlString(builder.ToString(), sqlParams);
            string key = base.GenerateCacheKey(entityType, OperationType.Delete);
            SqlString[] sql = new SqlString[] { str };
            CacheProxy.CacheSql(key, sql);
            return sql;
        }

        public override SqlString[] GenerateFindByKeySql(Type entityType, string[] properties)
        {
            ModelMappingInfo modelMappingInfo = AttMappingManager.Instance.GetModelMappingInfo(entityType);
            string mapTable = modelMappingInfo.MapTable;
            List<string> whereString = new List<string>();
            List<SqlParamInfo> sqlParams = new List<SqlParamInfo>();
            List<string> list3 = this.prepareUpdateSql(modelMappingInfo, properties, ref whereString, ref sqlParams);
            SqlString str2 = new SqlString(new StringBuilder("SELECT ").Append(string.Join(",", list3.ToArray())).Append(" FROM ").Append(mapTable).Append(" WHERE ").Append(string.Join(" AND ", whereString.ToArray())).ToString(), sqlParams);
            string key = base.GenerateCacheKey(entityType, OperationType.SelectByKey);
            SqlString[] sql = new SqlString[] { str2 };
            CacheProxy.CacheSql(key, sql);
            return sql;
        }

        public override SqlString[] GenerateInsertSql(Type entityType, string[] properties)
        {
            SqlString str = null;
            ModelMappingInfo modelMappingInfo = AttMappingManager.Instance.GetModelMappingInfo(entityType);
            string mapTable = modelMappingInfo.MapTable;
            List<string> parameters = new List<string>();
            List<SqlParamInfo> sqlParams = new List<SqlParamInfo>();
            List<string> list3 = this.prepareInsertSql(modelMappingInfo, properties, ref parameters, ref sqlParams);
            str = new SqlString(new StringBuilder("INSERT INTO ").Append(mapTable).Append("(").Append(string.Join(",", list3.ToArray())).Append(") VALUES(").Append(string.Join(",", parameters.ToArray())).Append(") ").ToString(), sqlParams);
            string key = base.GenerateCacheKey(entityType, OperationType.Insert);
            SqlString[] sql = new SqlString[] { str };
            CacheProxy.CacheSql(key, sql);
            return sql;
        }

        public override SqlString[] GenerateSimpleSelectSql(Type entityType, string[] properties)
        {
            ModelMappingInfo modelMappingInfo = AttMappingManager.Instance.GetModelMappingInfo(entityType);
            string mapTable = modelMappingInfo.MapTable;
            List<string> list = this.prepareSelectSql(modelMappingInfo, properties);
            SqlString str3 = new SqlString(new StringBuilder("SELECT ").Append(string.Join(",", list.ToArray())).Append(" FROM ").Append(mapTable).ToString(), null);
            string key = base.GenerateCacheKey(entityType, OperationType.Select);
            SqlString[] sql = new SqlString[] { str3 };
            CacheProxy.CacheSql(key, sql);
            return sql;
        }

        public override SqlString[] GenerateUpdateSql(Type entityType, string[] properties)
        {
            SqlString str = null;
            ModelMappingInfo modelMappingInfo = AttMappingManager.Instance.GetModelMappingInfo(entityType);
            string mapTable = modelMappingInfo.MapTable;
            List<string> whereString = new List<string>();
            List<SqlParamInfo> sqlParams = new List<SqlParamInfo>();
            List<string> list3 = this.prepareUpdateSql(modelMappingInfo, properties, ref whereString, ref sqlParams);
            StringBuilder builder = new StringBuilder();
            builder.Append(" UPDATE ").Append(mapTable).Append(" SET ").Append(string.Join(",", list3.ToArray())).Append(" WHERE ").Append(string.Join(" AND ", whereString.ToArray())).Append(" ;");
            str = new SqlString(builder.ToString(), sqlParams);
            string key = base.GenerateCacheKey(entityType, OperationType.Update);
            SqlString[] sql = new SqlString[] { str };
            CacheProxy.CacheSql(key, sql);
            return sql;
        }

        private List<string> prepareDeleteSql(ModelMappingInfo mappingInfo, ref List<SqlParamInfo> sqlParams)
        {
            List<string> list = new List<string>();
            sqlParams.Clear();
            foreach (FieldPropertyInfo info in mappingInfo.FieldPropertys.Values)
            {
                if (mappingInfo.PrimaryKeys.ContainsKey(info.FieldName))
                {
                    list.Add(info.FieldName + "=" + base.ParameterPrefix + info.FieldName);
                    sqlParams.Add(new SqlParamInfo(info.FieldName, DbShare.Instance.SystemTypeNameToDbType(info.DeclaringType.FullName)));
                }
            }
            return list;
        }

        private List<string> prepareFindByKeySql(ModelMappingInfo mappingInfo, string[] properties, ref List<string> whereString, ref List<SqlParamInfo> sqlParams)
        {
            List<string> list = new List<string>();
            whereString.Clear();
            sqlParams.Clear();
            bool flag = (properties != null) && (properties.Length > 0);
            foreach (FieldPropertyInfo info in mappingInfo.FieldPropertys.Values)
            {
                if (mappingInfo.PrimaryKeys.ContainsKey(info.FieldName))
                {
                    whereString.Add(info.FieldName + "=" + base.ParameterPrefix + info.FieldName);
                    sqlParams.Add(new SqlParamInfo(info.FieldName, DbShare.Instance.SystemTypeNameToDbType(info.DeclaringType.FullName)));
                }
                else if (!flag || (Array.IndexOf<string>(properties, info.FieldName) >= 0))
                {
                    list.Add(info.FieldName);
                }
            }
            return list;
        }

        private List<string> prepareInsertSql(ModelMappingInfo mappingInfo, string[] properties, ref List<string> parameters, ref List<SqlParamInfo> sqlParams)
        {
            parameters.Clear();
            sqlParams.Clear();
            List<string> list = new List<string>();
            bool flag = (properties != null) && (properties.Length > 0);
            foreach (FieldPropertyInfo info in mappingInfo.FieldPropertys.Values)
            {
                if (!flag || (Array.IndexOf<string>(properties, info.FieldName) >= 0))
                {
                    list.Add(info.FieldName);
                    parameters.Add(base.ParameterPrefix + info.FieldName);
                    sqlParams.Add(new SqlParamInfo(info.FieldName, DbShare.Instance.SystemTypeNameToDbType(info.DeclaringType.FullName)));
                }
            }
            return list;
        }

        private List<string> prepareSelectSql(ModelMappingInfo mappingInfo, string[] properties)
        {
            List<string> list = new List<string>();
            bool flag = (properties != null) && (properties.Length > 0);
            foreach (FieldPropertyInfo info in mappingInfo.FieldPropertys.Values)
            {
                if (!flag || (Array.IndexOf<string>(properties, info.FieldName) >= 0))
                {
                    list.Add(info.FieldName);
                }
            }
            return list;
        }

        private List<string> prepareUpdateSql(ModelMappingInfo mappingInfo, string[] properties, ref List<string> whereString, ref List<SqlParamInfo> sqlParams)
        {
            List<string> list = new List<string>();
            whereString.Clear();
            sqlParams.Clear();
            bool flag = (properties != null) && (properties.Length > 0);
            foreach (FieldPropertyInfo info in mappingInfo.FieldPropertys.Values)
            {
                if (mappingInfo.PrimaryKeys.ContainsKey(info.FieldName))
                {
                    whereString.Add(info.FieldName + "=" + base.ParameterPrefix + info.FieldName);
                }
                else if (!flag || (Array.IndexOf<string>(properties, info.FieldName) >= 0))
                {
                    list.Add(info.FieldName + "=" + base.ParameterPrefix + info.FieldName);
                }
                if ((mappingInfo.PrimaryKeys.ContainsKey(info.FieldName) || !flag) || (Array.IndexOf<string>(properties, info.FieldName) >= 0))
                {
                    sqlParams.Add(new SqlParamInfo(info.FieldName, DbShare.Instance.SystemTypeNameToDbType(info.DeclaringType.FullName)));
                }
            }
            return list;
        }
    }
}
